/**********************************************************************************************/
/* FBL_Value_Factories.cpp																	  */
/*                                                                       					  */
/* Copyright Paradigma, 1993-2006															  */
/* All Rights Reserved.                                                 					  */
/**********************************************************************************************/

#include <VShared/FBL/publ/Headers/StdAfx.h>

#include <VShared/FBL/publ/Values/Factories/FBL_Value_Factories.h>

// VShared/FBL/publ:
#include <VShared/FBL/publ/Interfaces/FBL_I_Localizable.h> 

#include <VShared/FBL/publ/Values/FBL_Value_Numeric.h>
#include <VShared/FBL/publ/Values/FBL_Value_String.h>
#include <VShared/FBL/publ/Values/FBL_Value_Text.h>
#include <VShared/FBL/publ/Values/FBL_Value_Binary.h>
#include <VShared/FBL/publ/Values/FBL_Value_Date.h>
#include <VShared/FBL/publ/Values/FBL_Value_Time.h>
#include <VShared/FBL/publ/Values/FBL_Value_DateTime.h>
#include <VShared/FBL/publ/Values/FBL_Value_Float.h>
#include <VShared/FBL/publ/Values/FBL_Value_Double.h>


/**********************************************************************************************/
FBL_Begin_Namespace


/**********************************************************************************************/
/**	Below is the set of factory functions to create values through 
	the map of registered value types. This way is slower than direct 
	creation but this is the only way to create values of the user-
	defined types. */


/**********************************************************************************************/
I_Value* CreateValueBoolean( bool inNullable, void* inParam1, void* inParam2 )
{
	argused2( inParam1, inParam2 );

	if( inNullable )
		return new Value_bool_null();
	else
		return new Value_bool();
}


/**********************************************************************************************/
I_Value* CreateValueByte( bool inNullable, void* inParam1, void* inParam2 )
{
	argused2( inParam1, inParam2 );
	
	if( inNullable )
		return new Value_byte_null();
	else
		return new Value_byte();
}


/**********************************************************************************************/
I_Value* CreateValueShort( bool inNullable, void* inParam1, void* inParam2 )
{
	argused2( inParam1, inParam2 );
	
	if( inNullable )
		return new Value_short_null();
	else
		return new Value_short();
}


/**********************************************************************************************/
I_Value* CreateValueUShort( bool inNullable, void* inParam1, void* inParam2 )
{
	argused2( inParam1, inParam2 );
	
	if( inNullable )
		return new Value_ushort_null();
	else
		return new Value_ushort();
}


/**********************************************************************************************/
I_Value* CreateValueLong( bool inNullable, void* inParam1, void* inParam2 )
{
	argused2( inParam1, inParam2 );
	
	if( inNullable )
		return new Value_long_null();
	else
		return new Value_long();
}


/**********************************************************************************************/
I_Value* CreateValueULong( bool inNullable, void* inParam1, void* inParam2 )
{
	argused2( inParam1, inParam2 );
	
	if( inNullable )
		return new Value_ulong_null();
	else
		return new Value_ulong();
}


/**********************************************************************************************/
I_Value* CreateValueLLong( bool inNullable, void* inParam1, void* inParam2 )
{
	argused2( inParam1, inParam2 );
	
	if( inNullable )
		return new Value_llong_null();
	else
		return new Value_llong();
}


/**********************************************************************************************/
I_Value* CreateValueULLong( bool inNullable, void* inParam1, void* inParam2 )
{
	argused2( inParam1, inParam2 );
	
	if( inNullable )
		return new Value_ullong_null();
	else
		return new Value_ullong();
}


/**********************************************************************************************/
I_Value* CreateValueFloat( bool inNullable, void* inParam1, void* inParam2 )
{
	ushort Precission = inParam1 ? *reinterpret_cast<ushort*>(inParam1) : gFloatDefaultPrecision;
	ushort Scale = inParam2 ? *reinterpret_cast<ushort*>(inParam2) : gFloatDefaultScale;
	
	if( inNullable )
		return new Value_float_null( Precission, Scale );
	else
		return new Value_float( Precission, Scale );
}


/**********************************************************************************************/
I_Value* CreateValueDouble( bool inNullable, void* inParam1, void* inParam2 )
{
	ushort Precission = inParam1 ? *reinterpret_cast<ushort*>(inParam1) : gDoubleDefaultPrecision;
	ushort Scale = inParam2 ? *reinterpret_cast<ushort*>(inParam2) : gDoubleDefaultScale;
	
	if( inNullable )
		return new Value_double_null( Precission, Scale );
	else
		return new Value_double( Precission, Scale );
}


/**********************************************************************************************/
I_Value* CreateValueString( bool inNullable, void* inParam1, void* inParam2 )
{
	//FBL_CHECK(inParam1);

	tslen MaxLen = inParam1 ? *reinterpret_cast<tslen*>(inParam1) : 20;
	
	I_Localizable* pLocalizable = (I_Localizable*) inParam2;
	
	if( inNullable )
		return new Value_string_null( MaxLen, pLocalizable );
	else
		return new Value_string( MaxLen, pLocalizable );
}


/**********************************************************************************************/
I_Value* CreateValueVarChar( bool inNullable, void* inParam1, void* inParam2 )
{
	argused1( inNullable );

	tslen MaxLen = inParam1 ? *reinterpret_cast<tslen*>(inParam1) : kMaxLengthOfVarChar_UTF16;

	I_Localizable* pLocalizable = (I_Localizable*) inParam2;
	
	if( inNullable )
		return new Value_varchar_null( MaxLen, pLocalizable );
	else
		return new Value_varchar( MaxLen, pLocalizable );
}


#pragma mark -


/**********************************************************************************************/
I_Value* CreateValueDate( bool inNullable, void* inParam1, void* inParam2 )
{
	argused1( inParam2 );
	
	if( !inParam1 )
	{
		// set default ?
	}
	
	const DTFormat* p = reinterpret_cast<const DTFormat*>(inParam1);

	if( inNullable )
		return new Value_date_null( p );
	else
		return new Value_date( p );
}


/**********************************************************************************************/
I_Value* CreateValueTime( bool inNullable, void* inParam1, void* inParam2 )
{
	argused1( inParam2 );
	
	if( !inParam1 )
	{
		// set default ?
	}
	
	const DTFormat* p = reinterpret_cast<const DTFormat*>(inParam1);
	
	if( inNullable )
		return new Value_time_null( p );
	else
		return new Value_time( p );
}


/**********************************************************************************************/
I_Value* CreateValueDateTime( bool inNullable, void* inParam1, void* inParam2 )
{
	argused1( inParam2 );
	
	if( !inParam1 )
	{
		// set default ?
	}
	
	const DTFormat* p = reinterpret_cast<const DTFormat*>(inParam1);
	
	if( inNullable )
		return new Value_datetime_null( p );
	else
		return new Value_datetime( p );
}


/**********************************************************************************************/
I_Value* CreateValueMedium( bool inNullable, void* inParam1, void* inParam2 )
{
	argused2( inParam1, inParam2 );
	
	if( inNullable )
		return new Value_medium_null();
	else
		return new Value_medium();
}


/**********************************************************************************************/
I_Value* CreateValueUMedium( bool inNullable, void* inParam1, void* inParam2 )
{
	argused2( inParam1, inParam2 );

	if( inNullable )
		return new Value_umedium_null();
	else
		return new Value_umedium();
}


#pragma mark -
#pragma mark ==== Binary Value Factories


/**********************************************************************************************/
I_Value* CreateValueFixedBinary( bool inNullable, void* inParam1, void* inParam2 )
{
	argused1( inParam2 );
	
	FBL_CHECK(inParam1);

	ushort MaxLen = *reinterpret_cast<ushort*>(inParam1);

	if( inNullable )
		return new Value_fixedbinary_null( MaxLen, 2 );
	else
		return new Value_fixedbinary( MaxLen, 2 );
}


/**********************************************************************************************/
I_Value* CreateValueVarBinary( bool inNullable, void* inParam1, void* inParam2 )
{
	argused1( inParam2 );
	
	FBL_CHECK(inParam1);

	ushort MaxLen = *reinterpret_cast<ushort*>(inParam1);
	
	if( inNullable )
		return new Value_varbinary_null( MaxLen, 0 );
	else
		return new Value_varbinary( MaxLen, 0 );
}


/**********************************************************************************************/
I_Value* CreateValueBLOB( bool inNullable, void* inParam1, void* inParam2 )
{
	argused3( inNullable, inParam1, inParam2 );

	return new Value_blob_null();
}


/**********************************************************************************************/
I_Value* CreateValuePicture( bool inNullable, void* inParam1, void* inParam2 )
{
	argused3( inNullable, inParam1, inParam2 );

	return new Value_picture_null();
}


/**********************************************************************************************/
I_Value* CreateValueText( bool inNullable, void* inParam1, void* inParam2 )
{
	argused1( inNullable );

	I_Localizable* pLocalizable = (I_Localizable*) inParam2;
	
	Value_text_null* pv = new Value_text_null( pLocalizable );

	// We return text value with a buffer of the required size.
	if( inParam1 )
		pv->ResizeChars( *(long*) inParam1 );
	
	return pv;
}


/**********************************************************************************************/
I_Value* CreateValueObjectPtr( bool inNullable, void* inParam1, void* inParam2 )
{
	argused2( inParam1, inParam2 );
	
	if( inNullable )
		return new Value_objectPtr_null();
	else
		return new Value_objectPtr();
}


/**********************************************************************************************/
FBL_End_Namespace
